package com.xuyifeng.callfilter;

import java.util.Date;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

/* An adapter to display customized view */
class LogCursorAdapter extends CursorAdapter {
	LogCursorAdapter(Context context, Cursor c) {
		super(context, c);
	}

	LogCursorAdapter(Context context, Cursor c, boolean autoRequery) {
		super(context, c, autoRequery);
	}

	@Override
	public void bindView (View view, Context context, Cursor cursor) {
		setViewData(view, cursor);
	}

	@Override
	public View	newView(Context context, Cursor cursor, ViewGroup parent)
	{
		RelativeLayout view;

		view = new RelativeLayout(context);
		String inflater = Context.LAYOUT_INFLATER_SERVICE;
		LayoutInflater vi = (LayoutInflater)context.getSystemService(inflater);
		vi.inflate(R.layout.log_list_item, view, true);
		setViewData(view, cursor);

		return view;
	}

	private void setViewData(View view, Cursor cursor) {
		TextView phoneView = (TextView)view.findViewById(R.id.log_phone);
		TextView dateView = (TextView)view.findViewById(R.id.log_date);
		TextView memoView = (TextView)view.findViewById(R.id.log_memo);
		String phoneStr = cursor.getString(cursor.getColumnIndexOrThrow(FilterDBAdapter.KEY_PHONE));
		phoneView.setText(phoneStr);
		Date date = new Date(cursor.getLong(cursor.getColumnIndexOrThrow(FilterDBAdapter.KEY_CREATION_DATE)));
		dateView.setText(date.toLocaleString());
		String memoStr = cursor.getString(cursor.getColumnIndexOrThrow(FilterDBAdapter.KEY_MEMO));
		memoView.setText(memoStr);
	}
}

public class LogListActivity extends Activity {

	FilterDBAdapter m_dbAdapter;
	Cursor m_cursor;
	/** Messenger for communicating with service. */
	Messenger m_service = null;
	boolean m_isBound = false;
	
	/**
	 * Handler of incoming messages from service.
	 */
	class IncomingHandler extends Handler {
	    @Override
	    public void handleMessage(Message msg) {
	        switch (msg.what) {
	            case CallFilterService.MSG_NEW_REJECT:
	               LogListActivity.this.m_cursor.requery();
	               break;
	            default:
	                super.handleMessage(msg);
	        }
	    }
	}
	
	/**
	 * Target we publish for clients to send messages to IncomingHandler.
	 */
	final Messenger m_messenger = new Messenger(new IncomingHandler());
	
	/**
	 * Class for interacting with the main interface of the service.
	 */
	private ServiceConnection m_connection = new ServiceConnection() {
	    public void onServiceConnected(ComponentName className,
	            IBinder service) {
	        m_service = new Messenger(service);

	        // We want to monitor the service for as long as we are
	        // connected to it.
	        try {
	            Message msg = Message.obtain(null,
	                    CallFilterService.MSG_REGISTER_CLIENT);
	            msg.replyTo = m_messenger;
	            m_service.send(msg);
	        } catch (RemoteException e) {
	            // In this case the service has crashed before we could even
	            // do anything with it; we can count on soon being
	            // disconnected (and then reconnected if it can be restarted)
	            // so there is no need to do anything here.
	        }
	    }

	    public void onServiceDisconnected(ComponentName className) {
	        // This is called when the connection with the service has been
	        // unexpectedly disconnected -- that is, its process crashed.
	        m_service = null;
	    }
	};

	void doBindService() {
	    // Establish a connection with the service.  We use an explicit
	    // class name because there is no reason to be able to let other
	    // applications replace our component.
	    bindService(new Intent(this, 
	            CallFilterService.class), m_connection, Context.BIND_AUTO_CREATE);
	    m_isBound = true;
	}

	void doUnbindService() {
	    if (m_isBound) {
	        // If we have received the service, and hence registered with
	        // it, then now is the time to unregister.
	        if (m_service != null) {
	            try {
	                Message msg = Message.obtain(null,
	                        CallFilterService.MSG_UNREGISTER_CLIENT);
	                msg.replyTo = m_messenger;
	                m_service.send(msg);
	            } catch (RemoteException e) {
	                // There is nothing special we need to do if the service
	                // has crashed.
	            }
	        }

	        // Detach our existing connection.
	        unbindService(m_connection);
	        m_isBound = false;
	    }
	}
	    
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.log_list_view);

		m_dbAdapter = new FilterDBAdapter(this);
		// Open or create the database
		m_dbAdapter.open();

		ListView listView = (ListView)findViewById(R.id.log_list);
		m_cursor = m_dbAdapter.getAllLogCursor();
		startManagingCursor(m_cursor);
		LogCursorAdapter adapter = new LogCursorAdapter(this, m_cursor);
		listView.setAdapter(adapter);
		registerForContextMenu(listView);
		doBindService();
	}

	@Override
	public void onDestroy() {
		m_cursor.close();
		m_dbAdapter.close();
		super.onDestroy();
	}
	
	@Override
	protected void onPause() {
		doUnbindService();
		super.onPause();
	}

	@Override
	protected void onResume() {
		super.onResume();
		doBindService();
		m_cursor.requery();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.log_list_menu, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case (R.id.menu_clear_all_logs):
			m_dbAdapter.clearAllLogs();
			m_cursor.requery();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}
}
